using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Threading;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 一个温度计的控件，支持显示摄氏度，华氏度的温度信息
	/// </summary>
	[Description("一个温度计控件，支持两种信息显示，也可以用来做纵向的进度条")]
	public class HslThermometer : UserControl
	{
		private StringFormat sf = null;

		private float value_start = -20f;

		private float value_max = 60f;

		private float value_current = 0f;

		private int m_version = 0;

		private float value_paint = 0f;

		private object hybirdLock;

		private Action m_UpdateAction;

		private bool isRenderText = false;

		private int segment_count = 8;

		private Color colorBorder = Color.Silver;

		private Color colorCenter = Color.WhiteSmoke;

		private Color colorTmp = Color.Tomato;

		private Color colorTmpBack = Color.LightGray;

		private Brush brushback = new SolidBrush(Color.LightGray);

		private string leftUnitText = "℃";

		private string rightUnitText = "°F";

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 获取或设置控件的背景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Transparent")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
			}
		}

		/// <summary>
		/// 获取或设置数值的起始值，默认为0
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置数值的起始值，默认为0")]
		[DefaultValue(-20f)]
		public float ValueStart
		{
			get
			{
				if (value_max <= value_start)
				{
					return value_start + 1f;
				}
				return value_start;
			}
			set
			{
				value_start = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置数值的最大值，默认为100
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置数值的最大值，默认为100")]
		[DefaultValue(60f)]
		public float ValueMax
		{
			get
			{
				if (value_max <= value_start)
				{
					return value_start + 1f;
				}
				return value_max;
			}
			set
			{
				value_max = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置数值的当前值，应该处于最小值和最大值之间
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置数值的当前值，默认为0")]
		[DefaultValue(0f)]
		public float Value
		{
			get
			{
				return value_current;
			}
			set
			{
				if (value != value_current)
				{
					value_current = value;
					int version = Interlocked.Increment(ref m_version);
					ThreadPool.QueueUserWorkItem(ThreadPoolUpdateProgress, version);
				}
			}
		}

		/// <summary>
		/// 获取或设置温度计的分割段数，最小为2，最大1000
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置温度计的分割段数，最小为2，最大100")]
		[DefaultValue(8)]
		public int SegmentCount
		{
			get
			{
				return segment_count;
			}
			set
			{
				if (value > 1 && value < 100)
				{
					segment_count = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置温度计的颜色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置温度计的前景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Tomato")]
		public Color TemperatureColor
		{
			get
			{
				return colorTmp;
			}
			set
			{
				colorTmp = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置温度计的颜色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置温度计的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Silver")]
		public Color TemperatureBackColor
		{
			get
			{
				return colorTmpBack;
			}
			set
			{
				colorTmpBack = value;
				brushback.Dispose();
				brushback = new SolidBrush(colorTmpBack);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置是否显示温度计的数值
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置是否显示温度计的数值")]
		[Category("HslControls")]
		[DefaultValue(false)]
		public bool IsRenderText
		{
			get
			{
				return isRenderText;
			}
			set
			{
				isRenderText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置左侧的单位显示文本，默认是℃
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置左侧的单位显示文本，默认是℃")]
		[Category("HslControls")]
		[DefaultValue("℃")]
		public string LeftUnitText
		{
			get
			{
				return leftUnitText;
			}
			set
			{
				leftUnitText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置右侧的单位显示文本，默认是°F
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置左侧的单位显示文本，默认是°F")]
		[Category("HslControls")]
		[DefaultValue("°F")]
		public string RightUnitText
		{
			get
			{
				return rightUnitText;
			}
			set
			{
				rightUnitText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置右侧轴的数值和左边的关系
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Func<float, float> RightDataTransfer
		{
			get;
			set;
		}

		/// <summary>
		/// 实例化一个温度控件对象
		/// </summary>
		public HslThermometer()
		{
			InitializeComponent();
			sf = new StringFormat();
			sf.Alignment = StringAlignment.Center;
			sf.LineAlignment = StringAlignment.Center;
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			RightDataTransfer = ((float m) => m * 1.8f + 32f);
			hybirdLock = new object();
			m_UpdateAction = base.Invalidate;
		}

		private void ThreadPoolUpdateProgress(object obj)
		{
			try
			{
				int version = (int)obj;
				if (value_paint == value_current)
				{
					return;
				}
				float m_speed = Math.Abs(value_paint - value_current) / 10f;
				if (m_speed == 0f)
				{
					m_speed = 1f;
				}
				while (value_paint != value_current)
				{
					Thread.Sleep(17);
					if (version != m_version)
					{
						break;
					}
					lock (hybirdLock)
					{
						float newActual = 0f;
						if (value_paint > value_current)
						{
							float offect2 = value_paint - value_current;
							if (offect2 > m_speed)
							{
								offect2 = m_speed;
							}
							newActual = value_paint - offect2;
						}
						else
						{
							float offect = value_current - value_paint;
							if (offect > m_speed)
							{
								offect = m_speed;
							}
							newActual = value_paint + offect;
						}
						value_paint = newActual;
					}
					if (version == m_version)
					{
						if (base.IsHandleCreated)
						{
							Invoke(m_UpdateAction);
						}
						continue;
					}
					break;
				}
			}
			catch (Exception)
			{
			}
		}

		/// <summary>
		/// 重新实现控件的界面绘制情况
		/// </summary>
		/// <param name="e">重绘的事件</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			if (!Authorization.iashdiadasbdnajsdhjaf())
			{
				return;
			}
			Graphics g = e.Graphics;
			g.SmoothingMode = SmoothingMode.AntiAlias;
			g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			Brush foreBrush = new SolidBrush(ForeColor);
			Pen pen = new Pen(ForeColor, 1f);
			float radius_mini = (float)base.Width * 0.1f;
			float radius_large = (float)base.Width * 0.2f;
			float top = radius_mini + 40f;
			float height_mid = (float)base.Height - top - 20f - radius_large * 2f;
			ColorBlend colorBlend = new ColorBlend();
			colorBlend.Positions = new float[4]
			{
				0f,
				0.3f,
				0.8f,
				1f
			};
			colorBlend.Colors = new Color[4]
			{
				colorCenter,
				colorBorder,
				colorCenter,
				colorBorder
			};
			LinearGradientBrush brush = new LinearGradientBrush(new PointF((float)base.Width / 2f - radius_mini * 0.7f, 0f), new PointF((float)base.Width / 2f + radius_mini * 0.7f, 0f), colorBorder, colorCenter);
			brush.InterpolationColors = colorBlend;
			g.FillEllipse(brushback, (float)base.Width / 2f - radius_mini, top - radius_mini, radius_mini * 2f, radius_mini * 2f);
			g.FillEllipse(brushback, (float)base.Width / 2f - radius_large, top + height_mid, radius_large * 2f, radius_large * 2f);
			g.FillRectangle(brushback, (float)base.Width / 2f - radius_mini, top, radius_mini * 2f, height_mid + radius_large);
			for (int i = 0; i <= segment_count; i++)
			{
				float valueTmp = (float)i * (value_max - value_start) / (float)segment_count + value_start;
				float paintTmp = height_mid - 10f - (valueTmp - value_start) / (value_max - value_start) * (height_mid - 10f) + top;
				if (i > 0)
				{
					for (int j = 1; j < 10; j++)
					{
						float segment_min = (height_mid - 10f) / (float)segment_count / 10f * (float)j;
						if (j == 5)
						{
							g.DrawLine(pen, (float)base.Width / 2f - radius_mini - (float)base.Width * 0.14f, paintTmp + segment_min, (float)base.Width / 2f - radius_mini - 4f, paintTmp + segment_min);
							g.DrawLine(pen, (float)base.Width / 2f + radius_mini + (float)base.Width * 0.14f, paintTmp + segment_min, (float)base.Width / 2f + radius_mini + 4f, paintTmp + segment_min);
						}
						else
						{
							g.DrawLine(pen, (float)base.Width / 2f - radius_mini - (float)base.Width * 0.1f, paintTmp + segment_min, (float)base.Width / 2f - radius_mini - 4f, paintTmp + segment_min);
							g.DrawLine(pen, (float)base.Width / 2f + radius_mini + (float)base.Width * 0.1f, paintTmp + segment_min, (float)base.Width / 2f + radius_mini + 4f, paintTmp + segment_min);
						}
					}
				}
				g.DrawLine(pen, (float)base.Width / 2f - radius_mini - (float)base.Width * 0.3f, paintTmp, (float)base.Width / 2f - radius_mini - 4f, paintTmp);
				g.DrawLine(pen, (float)base.Width / 2f + radius_mini + 4f, paintTmp, (float)base.Width / 2f + radius_mini + (float)base.Width * 0.3f, paintTmp);
				sf.Alignment = StringAlignment.Far;
				g.DrawString(rightUnitText, Font, foreBrush, new RectangleF(5f, 0f, base.Width - 10, top - radius_mini), sf);
				g.DrawString(valueTmp.ToString(), Font, foreBrush, new RectangleF(0f, paintTmp - (float)Font.Height - 1f, (float)base.Width / 2f - radius_mini - (float)base.Width * 0.14f, Font.Height + 1), sf);
				sf.Alignment = StringAlignment.Near;
				g.DrawString(leftUnitText, Font, foreBrush, new RectangleF(5f, 0f, base.Width - 10, top - radius_mini), sf);
				if (RightDataTransfer != null)
				{
					g.DrawString(Math.Round(RightDataTransfer(valueTmp)).ToString(), Font, foreBrush, new RectangleF((float)base.Width / 2f + radius_mini + (float)base.Width * 0.1f + 5f, paintTmp - (float)Font.Height - 1f, (float)base.Width * 0.4f, Font.Height + 1), sf);
				}
			}
			g.FillEllipse(brush, (float)base.Width / 2f - radius_mini * 0.7f, top - radius_mini * 0.7f, radius_mini * 1.4f, radius_mini * 1.4f);
			g.FillRectangle(brush, (float)base.Width / 2f - radius_mini * 0.7f, top, radius_mini * 1.4f, height_mid + radius_large);
			colorBlend.Colors = new Color[4]
			{
				colorTmp,
				colorTmp,
				colorCenter,
				colorTmp
			};
			brush.InterpolationColors = colorBlend;
			float paintCurrent = height_mid - 10f - (value_paint - value_start) / (value_max - value_start) * (height_mid - 10f) + top;
			if (paintCurrent < top - 5f)
			{
				paintCurrent = top - 5f;
			}
			if (paintCurrent > top + height_mid + 5f)
			{
				paintCurrent = top + height_mid + 5f;
			}
			g.FillRectangle(brush, (float)base.Width / 2f - radius_mini * 0.7f, paintCurrent, radius_mini * 1.4f, height_mid + radius_large + top - paintCurrent);
			using (Brush brushTmp = new SolidBrush(colorTmp))
			{
				g.FillEllipse(brushTmp, (float)base.Width / 2f - radius_mini * 0.7f, paintCurrent - 1f, radius_mini * 1.4f, 3f);
			}
			RectangleF rectangleCircle = new RectangleF((float)base.Width / 2f - radius_large * 0.85f, top + height_mid + radius_large * 0.15f, radius_large * 1.7f, radius_large * 1.7f);
			GraphicsPath path = new GraphicsPath();
			path.AddEllipse(rectangleCircle);
			PathGradientBrush brushCircle = new PathGradientBrush(path);
			brushCircle.CenterPoint = new PointF((float)base.Width / 2f + radius_large * 0.2f, top + height_mid + radius_large * 0.7f);
			ColorBlend colorBlendCircle = new ColorBlend();
			colorBlendCircle.Positions = new float[2]
			{
				0f,
				1f
			};
			colorBlendCircle.Colors = new Color[2]
			{
				colorTmp,
				colorCenter
			};
			brushCircle.InterpolationColors = colorBlendCircle;
			e.Graphics.FillEllipse(brushCircle, rectangleCircle);
			using (Pen penCircle = new Pen(colorTmp))
			{
				e.Graphics.DrawEllipse(penCircle, rectangleCircle);
			}
			brushCircle.Dispose();
			path.Dispose();
			if (isRenderText)
			{
				sf.Alignment = StringAlignment.Center;
				g.DrawString(value_current.ToString(), Font, foreBrush, new RectangleF((float)base.Width / 2f - radius_large, top + height_mid, radius_large * 2f, radius_large * 2f), sf);
			}
			brush.Dispose();
			foreBrush.Dispose();
			pen.Dispose();
			base.OnPaint(e);
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.Transparent;
			base.Name = "HslThermometer";
			base.Size = new System.Drawing.Size(140, 201);
			ResumeLayout(false);
		}
	}
}
